package com.dynamicthreadpool.dubbo;

import com.dynamicthreadpool.core.DynamicThreadPool;
import com.dynamicthreadpool.factory.ThreadFactoryFactory;

import com.dynamicthreadpool.spi.URL;
import com.dynamicthreadpool.strategy.QueueStrategyFactory;
import com.dynamicthreadpool.strategy.RejectStrategyFactory;

import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;

/**
 * 动态线程池工厂实现
 * 实现自定义的ThreadPool接口，通过SPI机制加载
 */
public class DynamicThreadPoolFactory {

    // 默认参数
    private static final int DEFAULT_CORE_THREADS = 10;
    private static final int DEFAULT_MAX_THREADS = 200;
    private static final int DEFAULT_QUEUE_CAPACITY = 200;
    private static final long DEFAULT_KEEP_ALIVE_TIME = 60000L;
    private static final String DEFAULT_QUEUE_TYPE = "ResizeableArrayBlockingQueue";
    private static final String DEFAULT_REJECT_POLICY = "abort";
    private static final String DEFAULT_THREAD_NAME = "dynamic-threadpool";

    /**
     * 根据URL创建动态线程池
     * @param url 包含线程池配置的URL
     * @return 动态线程池实例
     */
    public static Executor getExecutor(URL url) {
        // 从URL中获取配置参数
        int coreThreads = url.getParameter("corethreads", DEFAULT_CORE_THREADS);
        int maxThreads = url.getParameter("maxthreads", DEFAULT_MAX_THREADS);
        int queueCapacity = url.getParameter("queues", DEFAULT_QUEUE_CAPACITY);
        long keepAliveTime = url.getParameter("keepalive", DEFAULT_KEEP_ALIVE_TIME);
        String queueType = url.getParameter("queueType", DEFAULT_QUEUE_TYPE);
        String rejectPolicy = url.getParameter("rejectPolicy", DEFAULT_REJECT_POLICY);
        String threadName = url.getParameter("threadname", DEFAULT_THREAD_NAME);

        // 创建动态线程池
        DynamicThreadPool threadPool = new DynamicThreadPool(
                coreThreads,
                maxThreads,
                keepAliveTime,
                TimeUnit.MILLISECONDS,
                queueCapacity,
                queueType,
                threadName,
                rejectPolicy
        );

        // 设置是否允许核心线程超时
        threadPool.allowCoreThreadTimeOut(url.getParameter("allowCoreThreadTimeout", false));

        return threadPool;
    }

    /**
     * 根据URL参数更新已存在的动态线程池
     * @param executor 现有的执行器
     * @param url 包含新参数的URL
     */
    public static void updateThreadPool(Executor executor, URL url) {
        if (executor instanceof DynamicThreadPool) {
            DynamicThreadPool dynamicThreadPool = (DynamicThreadPool) executor;

            // 动态更新参数
            dynamicThreadPool.setCorePoolSize(url.getParameter("corethreads", dynamicThreadPool.getCorePoolSize()));
            dynamicThreadPool.setMaximumPoolSize(url.getParameter("maxthreads", dynamicThreadPool.getMaximumPoolSize()));
            dynamicThreadPool.setKeepAliveTime(
                    url.getParameter("keepalive", dynamicThreadPool.getKeepAliveTime(TimeUnit.MILLISECONDS)),
                    TimeUnit.MILLISECONDS
            );
            dynamicThreadPool.setPoolName(url.getParameter("threadname", dynamicThreadPool.getPoolName()));
            dynamicThreadPool.setRejectPolicy(url.getParameter("rejectPolicy", "abort"));

            // 动态更新队列容量
            int newQueueCapacity = url.getParameter("queues", dynamicThreadPool.getQueueCapacity());
            if (newQueueCapacity != dynamicThreadPool.getQueueCapacity()) {
                dynamicThreadPool.setQueueCapacity(newQueueCapacity);
            }
        }
    }
}
